using System;
using System.Diagnostics;

namespace FrameWork
{
    public partial class ObjectPoolModule 
    {
        private sealed class Object<T> : IReference where T : ObjectBase
        {
            private T _object;

            private int _spawnCount;

            public Object()
            {
                _object = null;
                _spawnCount = 0;
            }

            public string Name
            {
                get => _object.Name;
            }

            public DateTime LastUseTime
            {
                get => _object.LastUseTime;
            }

            /// <summary>
            /// 获取对象是否正在被使用
            /// </summary>
            public bool IsInUse
            {
                get => _spawnCount > 0;
            }

            /// <summary>
            /// 获取对象的Fetch计数
            /// </summary>
            public int SpawnCount
            {
                get => _spawnCount;
            }

            public static Object<T> Create(T obj,bool spawned)
            {
                if (obj == null)
                    throw new NullReferenceException("Object is null");

                Object<T> internalObject = ReferencePool.Acquire<Object<T>>();
                internalObject._object = obj;
                internalObject._spawnCount = spawned ? 1 : 0;
                if (spawned)
                    obj.OnSpawn();

                return internalObject;
            }

            public void Clear()
            {
                _object = null;
                _spawnCount = 0;
            }

            /// <summary>
            /// 查看对象
            /// </summary>
            public T Peek()
            {
                return _object;
            }

            /// <summary>
            /// 获取对象
            /// </summary>
            public T Spawn()
            {
                _spawnCount++;
                _object.LastUseTime = DateTime.UtcNow;
                _object.OnSpawn();
                return _object;
            }

            /// <summary>
            /// 回收对象
            /// </summary>
            public void UnSpawn()
            {
                _object.OnUnSpawn();
                _object.LastUseTime = DateTime.UtcNow;
                _spawnCount--;
                if (_spawnCount < 0)
                {
                    throw new Exception($"{Name} unspawn Count less  {_spawnCount} < 0");
                }
            }

            public void Release(bool isShutDown)
            {
                _object.Release();
                ReferencePool.Recycle(_object);
            }
        }
    }
}

